package com.ruipeng.shengyapo.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import net.sf.ezmorph.Morpher;
import net.sf.ezmorph.MorpherRegistry;
import net.sf.ezmorph.bean.BeanMorpher;
import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONObject;
import net.sf.json.util.JSONUtils;

import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


/**
 * http 相关工具类
 * @author zhenchb
 */
public final class HttpUtils {
	
	/** 请求： 0： "失败" */
	public final static boolean STATE_FALSE = false;
	/** 请求状态： 1："成功" */
	public final static boolean STATE_TRUE = true;

	public final static String CURRENT_USER_4_MAP = "CURRENT_USER_4_MAP";
	public final static String CURRENT_USER_4_POJO = "CURRENT_USER_4_POJO";
	
	public final static String HTTP_POST = "POST";
	
	public final static String HTTP_GET = "GET";

	/**
	 * 从session 中获取 user pojo Obj对象
	 * @param request
	 * @return
	 */
	public final static Object getUserInfo4Bean(HttpServletRequest request) {
		HttpSession session = request.getSession();
		Object obj = session.getAttribute(CURRENT_USER_4_POJO);
		return ObjUtils.isEmpty(obj)? null : obj;
	}

	/**
	 * 从session 中获取 user pojo Obj对象
	 * @return
	 */
	public final static Object getUserInfo4Bean() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		return getUserInfo4Bean(request);
	}

	/**
	 * 将user pojo 对象放入session作用域中
	 * @param request
	 * @param userPojo
	 */
	public final static void setUserPojo2Session(HttpServletRequest request, Object userPojo) {
		HttpSession session = request.getSession();
		session.setAttribute(CURRENT_USER_4_POJO, userPojo);
	}

	/**
	 * 从session 中获取 user map对象
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public final static Map<String, Object> getUserMap(HttpServletRequest request) {
		HttpSession session = request.getSession();
		Object obj = session.getAttribute(CURRENT_USER_4_MAP);
		return ObjUtils.isEmpty(obj)? null : (Map<String, Object>) obj;
	}

	/**
	 * 从session 中获取 user map对象
	 * @return
	 */
	public final static Map<String, Object> getUserMap() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		return getUserMap(request);
	}

	/**
	 * 将user map 对象放入session作用域中
	 * @param request
	 * @param userMap
	 */
	public final static void setUserMap2Session(HttpServletRequest request, Map<String, Object> userMap) {
		HttpSession session = request.getSession();
		session.setAttribute(CURRENT_USER_4_MAP, userMap);
	}

	/**
	 * 构建返回结果
	 * @param state
	 * @param msg
	 * @param results
	 * @return
	 */
	public static Map<String, Object> buildResponseBody4Map(boolean state, String msg, Object results) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("state", state);
		map.put("msg", msg);
		map.put("results", results);
		return map;
	}

	/**
	 * 构建返回结果
	 * @param state
	 * @param msg
	 * @return
	 */
	public static Map<String, Object> buildResponseBody4Map(boolean state, String msg) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("state", state);
		map.put("msg", msg);
		return map;
	}

	/**
	 * 构建返回结果
	 * @param state {state ? "操作成功！": "操作失败！"}
	 * @return
	 */
	public static Map<String, Object> buildResponseBody4Map(boolean state) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("state", state);
		map.put("msg", state ? "操作成功！" : "操作失败！");
		return map;
	}

	/**
	 * 构建返回结果
	 * @param state
	 * @param results
	 * @return
	 */
	public static Map<String, Object> buildResponseBody4Map(boolean state, Object results) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("state", state);
		map.put("msg", state ? "操作成功！" : "操作失败！");
		map.put("results", results);
		return map;
	}
	
	/**
	 * 将 JSONObject 对象转换为 Map 对象
	 * @param jsonObj
	 * @return
	 */
	public static Map<String, Object> JsonObj2Map(JSONObject jsonObj){
		Map<String, Object> map = new HashMap<String, Object>();
		if(!jsonObj.isEmpty()){
			for (Object keyObj : jsonObj.keySet()) {
				map.put(keyObj.toString(), jsonObj.get(keyObj));
			}
		}
		return map;
	}

	/**
	 * 将  JSON String 对象转换为 Map 对象
	 * @return
	 */
	public static Map<String, Object> JsonObj2Map(String jsonStr){
		JSONObject jsonObj = JSONObject.fromObject(jsonStr);
		Map<String, Object> map = new HashMap<String, Object>();
		if(!jsonObj.isEmpty()){
			for (Object keyObj : jsonObj.keySet()) {
				map.put(keyObj.toString(), jsonObj.get(keyObj));
			}
		}
		return map;
	}
	
	 /**
     * json string convert to map with javaBean
     */
	@SuppressWarnings("unchecked")
    public static <T> Map<String,T> json2map(String jsonStr, Class<T> clazz){
    	JSONObject jsonObj = JSONObject.fromObject(jsonStr);
    	Map<String,T> map = new HashMap<String, T>();
		Map<String,T> result = (Map<String, T>) JSONObject.toBean(jsonObj, Map.class, map);
    	MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
    	Morpher dynaMorpher = new BeanMorpher(clazz,morpherRegistry);
    	morpherRegistry.registerMorpher(dynaMorpher);
    	morpherRegistry.registerMorpher(new DateMorpher(new String[]{ "yyyy-MM-dd HH:mm:ss" }));
    	for (Entry<String,T> entry : result.entrySet()) {
			map.put(entry.getKey(), (T)morpherRegistry.morph(clazz, entry.getValue()));
		}
    	return map;
    }

	public static Map<String, Object> getReqParams(HttpServletRequest request, String... params){
		Map<String, Object> map = new HashMap<String, Object>();
		if(params == null || params.length <= 0){
			return map;
		}
		
		for (String str : params) {
			String value = request.getParameter(str);
			if(StringUtils.isEmpty(value))
				continue;
			map.put(str, value);
		}
		return map;
	}
	
	public static Map<String, Object> getAllReqParams(HttpServletRequest request){
		Map<String, Object> map = new HashMap<String, Object>();
		@SuppressWarnings("unchecked")
		Enumeration<String> paramEn = request.getParameterNames();
		if(paramEn == null){
			return map;
		}
		String str = null;
		while(paramEn.hasMoreElements()){
			str = paramEn.nextElement();
			String value = request.getParameter(str);
			if(StringUtils.isEmpty(value))
				continue;
			map.put(str, value);
		}
		return map;
	}
	

	/**
	 * 向指定 URL 发送POST方法的请求
	 * @param url 发送请求的 URL
	 * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式或者为json字符串。
	 * @return 所代表远程资源的响应结果
	 */
	public static String sendPost(String url, String param) {
		OutputStreamWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();

			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setReadTimeout(20000);
			conn.setConnectTimeout(20000);
			// 获取URLConnection对象对应的输出流
			conn.setRequestProperty("Content-type", "application/json");
			conn.setRequestProperty("Accept-Charset", "UTF-8");
			out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");

			// 发送请求参数
			out.write(param);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常！" + e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}
}
